package ferp.core.ai.strategy.simple;

import ferp.core.calc.Calculator;
import ferp.core.game.Bid;
import ferp.core.game.Game;
import ferp.core.game.Settings;
import ferp.core.log.Log;
import ferp.core.player.AI;

/**
 * User: olegs
 * Date: 4/16/14 10:27 PM
 */
public class Simulate
{
  // get player's balance after simulating passing game
  public static long pass(Game g, Settings settings, AI ai)
  {
    Calculator c = Calculator.get(settings.gameFlavor);
    int tricks = Estimate.passes(g.getHand(ai.id()).current);
    int half = tricks / 2;
    Game simulated = g.clone();

    // assign estimated tricks to the players (best case scenario)
    simulated.setTricks(ai.id(), tricks);
    simulated.setTricks(Game.next(ai.id()), half);
    simulated.setTricks(Game.previous(ai.id()), Game.MAXIMUM_TRICKS - tricks - half);

    c.passing(simulated, settings);

    long delta = simulated.getScore(ai.id()).balance2.delta;

    Log.debug(Log.TAG, "simulated pass delta: " + delta + ", estimated tricks: " + tricks);

    return delta;
  }

  // get player's balance after simulating tricking game
  public static long play(Game g, Settings settings, AI ai, Bid minimum, Bid estimated)
  {
    Calculator c = Calculator.get(settings.gameFlavor);
    Bid contract = new Bid(estimated);
    Bid pass = Bid.pass();
    Game simulated = g.clone();

    // ensure proper minimum tricks number of player's bid
    contract.adjust(minimum);

    Bid whist = Bid.whist(Game.MAXIMUM_TRICKS - contract.tricks);

    // set required game data
    simulated.passers = 1;
    simulated.whisters = 1;
    simulated.player.declarer = ai.id();
    simulated.setBid(ai.id(), contract, contract);
    simulated.player.opponent = Game.next(simulated.player.declarer);
    simulated.setBid(simulated.player.opponent, whist, whist);
    simulated.player.passer = Game.next(simulated.player.opponent);
    simulated.setBid(simulated.player.passer, pass, pass);
    simulated.bid = contract;

    simulated.setTricks(ai.id(), estimated.tricks);
    simulated.setTricks(simulated.player.opponent, Game.MAXIMUM_TRICKS - estimated.tricks);

    c.tricking(simulated, settings);

    long delta = simulated.getScore(ai.id()).balance2.delta;

    Log.debug(Log.TAG, "simulated play delta: " + delta + ", estimated tricks: " + estimated.tricks);

    return delta;
  }

  // get player's balance after simulating 'without 3' game
  public static long without3(Game g, Settings settings, AI ai, Bid minimum, Bid estimated)
  {
    Calculator c = Calculator.get(settings.gameFlavor);
    Bid contract = new Bid(estimated);
    Game simulated = g.clone();

    contract.adjust(minimum);

    simulated.player.declarer = ai.id();
    simulated.setBid(ai.id(), contract, contract);
    simulated.bid = contract;

    c.trickingWithout3(simulated, settings);

    long delta = simulated.getScore(ai.id()).balance2.delta;

    Log.debug(Log.TAG, "simulated without3 delta: " + delta + ", estimated tricks: " + estimated.tricks);

    return delta;
  }
}
